package com.synjones.handsetS8;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;

import com.finger.FingerModule;
import com.finger.FingerUtil;
import com.synjones.cardutil.util;
import com.synjones.hymodule.Bytes2Bmp;

import java.util.HashMap;
import java.util.Map;

import cn.com.aratek.fp.Bione;
import cn.com.aratek.fp.FingerprintImage;
import cn.com.aratek.fp.FingerprintScanner;
import cn.com.aratek.util.OnUsbPermissionGrantedListener;
import cn.com.aratek.util.Result;

/**
 * Created by zhaodianbo on 2016-8-22.
 */
public class S8AbUsbModule implements FingerprintReaderInterface {
    //声明设备
    Context context;
    Handler outHandler;
    final String TAG=getClass().getSimpleName();
    int sensorType=1;//1=大指纹头，2=小指纹头
    private FingerprintScanner mScanner;
    private boolean mDeviceOpened;
    final String dbPath= Environment.getExternalStorageDirectory().getPath()+"/fp.db";
    volatile boolean isScaning=false;
    Bitmap bitmapFinger;
    byte fpFea[];
    //mVendorId=10477,mProductId=8259,
    //Supported_VID_PID.add("28ED:2043");
    public S8AbUsbModule(Context context, Handler handler){
        this.context=context;
        outHandler=handler;
        mScanner = new FingerprintScanner(context);
    }
    @Override
    public void powerOn() {
        if(WtWdPowerUtils.getFingerUSBPower(context)!=1)
            WtWdPowerUtils.setFingerUSBPower(context);
        UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        HashMap<String,UsbDevice> deviceHashMap=usbManager.getDeviceList();
        PendingIntent pi1 = PendingIntent.getBroadcast(context, 0, new Intent("cn.com.aratek.fp.USB_PERMISSION"), 0);
        try{
            usbManager.requestPermission((UsbDevice)((Map.Entry)deviceHashMap.entrySet().iterator().next()).getValue(), pi1);
        }catch (Exception e){}
    }

    @Override
    public void powerOff() {
        close();
        WtWdPowerUtils.closeFingerUSBPower(context);//关闭
    }

    @Override
    public int open() {
        if(mDeviceOpened) return 0;
        mScanner.setOnUsbPermissionGrantedListener(new OnUsbPermissionGrantedListener() {
            @Override
            public void onUsbPermissionGranted(boolean isGranted) {
                if (isGranted) {
                    Log.e(TAG,"sn="+(String) mScanner.getSN().data);
                    Log.e(TAG,"fw="+(String) mScanner.getFirmwareVersion().data);
                }
            }
        });
        int error;
        if ((error = mScanner.open()) != FingerprintScanner.RESULT_OK) {
           return error;
        }
        if ((error = Bione.initialize(context,dbPath)) != Bione.RESULT_OK) {
            return error;
        }
        mDeviceOpened = true;
        Log.i(TAG, "Fingerprint algorithm version: " + Bione.getVersion());
        return 0;
    }

    public int getSensorType(){
        return sensorType;
    }


    @Override
    public int close() {
        if(!mDeviceOpened)  return 0;
        int error;

        if ((error = mScanner.close()) != FingerprintScanner.RESULT_OK) {
            return error;
        }
        if ((error = Bione.exit()) != Bione.RESULT_OK) {
            return error;
        }
        mDeviceOpened = false;
        return 0;
    }

    @Override
    public int cleanFpFeature() {
        fpFea=null;
        return 0;
    }

    @Override
    public FpFeature getFpFeature(boolean showFpImage) {
        if(isScaning) return null;
        isScaning=true;
        long startTime, captureTime = -1, extractTime = -1, generalizeTime = -1, verifyTime = -1;
        FingerprintImage fi = null;
        byte[] fpFeat = null, fpTemp = null;
        int quality=0;
        Result res = null;
        sendMsg(MESSAGE_UPDATE_STATUS,"请放置手指");

        mScanner.prepare();
        do {
            try{
                startTime = System.currentTimeMillis();
                res = mScanner.capture();
                Log.e(TAG,"mScanner ret="+res.error);
                captureTime = System.currentTimeMillis() - startTime;
                fi = (FingerprintImage) res.data;
                Log.i(TAG, "Fingerprint image quality is " + Bione.getFingerprintQuality(fi));

                startTime = System.currentTimeMillis();
                res = Bione.extractFeature(fi);
                extractTime = System.currentTimeMillis() - startTime;
                if (res.error != Bione.RESULT_OK) {
                    //showErrorDialog(getString(R.string.enroll_failed_because_of_extract_feature), getFingerprintErrorString(res.error));
                    continue;
                }
                fpFeat = (byte[]) res.data;
                Log.e("tttt","feaLen="+fpFeat.length);
                break;

            }catch (Exception e){
                e.printStackTrace();
            }
        } while (res.error != FingerprintScanner.RESULT_OK && isScaning);

        isScaning=false;
        mScanner.finish();

        fpFeat = (byte[]) res.data;
        if(fpFeat!=null) {
            sendMsg(MESSAGE_UPDATE_STATUS,"获取指纹成功");
            byte[] fpBmp = null;
            bitmapFinger=null;
            if(showFpImage) {
                if (fi == null || (fpBmp = fi.convert2Bmp()) == null || (bitmapFinger = BitmapFactory.decodeByteArray(fpBmp, 0, fpBmp.length)) == null) {
                    bitmapFinger = null;
                }
            }
            return new FpFeature(bitmapFinger, quality, fpFeat, "");
        }
        sendMsg(MESSAGE_UPDATE_STATUS,"获取指纹失败");
        return  null;
    }


    @Override
    public int setFpFeature(int toWhere, byte[] data) {
        fpFea=data;
        return 0;
    }

    @Override
    public FpVerifyResult verifyFp(int sThreshold) {
        if(isScaning) return null;
        if (fpFea == null)
        {
            sendMsg(MESSAGE_UPDATE_STATUS,"请先录入指纹或下载模板!");
            return null;
        }
        long startTime, captureTime = -1, extractTime = -1, generalizeTime = -1, verifyTime = -1;
        FingerprintImage fi = null;
        byte[] fpFeat = null, fpTemp = null;
        int quality=0;
        Result res;

        try{
            do {

                sendMsg(MESSAGE_UPDATE_STATUS,"请放置手指");
                fpFeat = getFpFeature(true).characteristic;
                startTime = System.currentTimeMillis();
                if(fpFea.length==512){
                    res=Bione.idcardVerify(fpFea,fpFeat);
                }else
                    res = Bione.verify(fpFea, fpFeat);
                verifyTime = System.currentTimeMillis() - startTime;
                if (res.error != Bione.RESULT_OK) {
                    sendMsg(MESSAGE_UPDATE_STATUS,"比对失败:"+getFingerprintErrorString(res.error));
                    return new FpVerifyResult(false,0,0);
                }
                if ((Boolean) res.data) {
                    return new FpVerifyResult(true,100,0);
                }

            } while (false);
        }catch (Exception e){
            e.printStackTrace();
            Log.e(TAG,e.getMessage());
        }finally {
            isScaning=false;
        }

        return new FpVerifyResult(false,0,0);
    }

    @Override
    public void cancel() {
        isScaning=false;
    }

    @Override
    public int calibration() {
        return -1;
    }


    private void sendMsg(int what,Object msg){
        if(outHandler!=null)
            outHandler.obtainMessage(what,msg).sendToTarget();
    }

    private String getFingerprintErrorString(int error) {
        switch (error) {
            case FingerprintScanner.RESULT_OK:
                return ErrorString.operation_successful;
            case FingerprintScanner.RESULT_FAIL:
                return ErrorString.error_operation_failed;
            case FingerprintScanner.WRONG_CONNECTION:
                return ErrorString.error_wrong_connection;
            case FingerprintScanner.DEVICE_BUSY:
                return ErrorString.error_device_busy;
            case FingerprintScanner.DEVICE_NOT_OPEN:
                return ErrorString.error_device_not_open;
            case FingerprintScanner.TIMEOUT:
                return ErrorString.error_timeout;
            case FingerprintScanner.NO_PERMISSION:
                return ErrorString.error_no_permission;
            case FingerprintScanner.WRONG_PARAMETER:
                return ErrorString.error_wrong_parameter;
            case FingerprintScanner.DECODE_ERROR:
                return ErrorString.error_decode;
            case FingerprintScanner.INIT_FAIL:
                return ErrorString.error_initialization_failed;
            case FingerprintScanner.UNKNOWN_ERROR:
                return ErrorString.error_unknown;
            case FingerprintScanner.NOT_SUPPORT:
                return ErrorString.error_not_support;
            case FingerprintScanner.NOT_ENOUGH_MEMORY:
                return ErrorString.error_not_enough_memory;
            case FingerprintScanner.DEVICE_NOT_FOUND:
                return ErrorString.error_device_not_found;
            case FingerprintScanner.DEVICE_REOPEN:
                return ErrorString.error_device_reopen;
            case FingerprintScanner.NO_FINGER:
                return ErrorString.error_no_finger;
            case Bione.INITIALIZE_ERROR:
                return ErrorString.error_algorithm_initialization_failed;
            case Bione.INVALID_FEATURE_DATA:
                return ErrorString.error_invalid_feature_data;
            case Bione.BAD_IMAGE:
                return ErrorString.error_bad_image;
            case Bione.NOT_MATCH:
                return ErrorString.error_not_match;
            case Bione.LOW_POINT:
                return ErrorString.error_low_point;
            case Bione.NO_RESULT:
                return ErrorString.error_no_result;
            case Bione.OUT_OF_BOUND:
                return ErrorString.error_out_of_bound;
            case Bione.DATABASE_FULL:
                return ErrorString.error_database_full;
            case Bione.LIBRARY_MISSING:
                return ErrorString.error_library_missing;
            case Bione.UNINITIALIZE:
                return ErrorString.error_algorithm_uninitialize;
            case Bione.REINITIALIZE:
                return ErrorString.error_algorithm_reinitialize;
            case Bione.REPEATED_ENROLL:
                return ErrorString.error_repeated_enroll;
            case Bione.NOT_ENROLLED:
                return ErrorString.error_not_enrolled;
            default:
                return ErrorString.error_other;
        }
    }

    static class ErrorString{
        public static String info_error = "错误";
        public static String operation_successful = "操作成功！";
        public static String error_operation_failed = "操作失败！";
        public static String error_wrong_connection = "连接错误导致操作失败！";
        public static String error_device_busy = "设备忙导致操作失败！";
        public static String error_device_not_open = "设备未打开导致操作失败！";
        public static String error_timeout = "传输超时导致操作失败！";
        public static String error_no_permission = "无操作权限导致操作失败！";
        public static String error_wrong_parameter = "输入参数错误导致操作失败！";
        public static String error_decode = "解码错误导致操作失败！";
        public static String error_initialization_failed = "设备初始化失败导致操作失败！";
        public static String error_unknown = "未知错误导致操作失败！";
        public static String error_not_support = "不被支持的操作导致操作失败！";
        public static String error_not_enough_memory = "内存不足导致操作失败！";
        public static String error_device_not_found = "未能找到设备导致操作失败！";
        public static String error_device_reopen = "设备重复打开导致操作失败！";
        public static String error_algorithm_initialization_failed = "指纹算法初始化失败导致操作失败！";
        public static String error_invalid_feature_data = "指纹特征数据错误导致操作失败！";
        public static String error_bad_image = "指纹图像太差导致操作失败！";
        public static String error_not_match = "指纹不匹配导致操作失败！";
        public static String error_low_point = "指纹比对分值太低导致操作失败！";
        public static String error_no_finger = "无手指导致操作失败！";
        public static String error_no_result = "指纹库中无匹配指纹导致操作失败！";
        public static String error_out_of_bound = "输入指纹ID越界导致操作失败！";
        public static String error_database_full = "指纹库已满导致操作失败！";
        public static String error_library_missing = "指纹算法库丢失导致操作失败！";
        public static String error_algorithm_uninitialize = "指纹算法未初始化导致操作失败！";
        public static String error_algorithm_reinitialize = "指纹算法重复初始化导致操作失败！";
        public static String error_repeated_enroll = "指纹重复注册导致操作失败！";
        public static String error_not_enrolled = "指纹未注册导致操作失败！";
        public static String error_no_card = "未能找到卡片导致操作失败！";
        public static String error_invalid_card = "卡片无效导致操作失败！";
        public static String error_invalid_decode_lib = "卡片解码库无效导致操作失败！";
        public static String error_other = "其它错误导致操作失败！";
    }


}
